﻿#include "tcpclient.h"
#include <mainwindow.h>
#include <samplewindow.h>

TcpClient* TcpClient::Instance=0;
extern intListener recfl;
extern QString recvvalue;
QString allerror;
extern intListener infochan;
// 指令结构体
struct order
{
    // 可以添加一个函数来序列化结构体
    QByteArray toByteArray(QString header,QString type,QString len,QString data,QString cd,QString tail) const {
        QString all = header+type+len+data+cd+tail;
        QByteArray byteArray;
        for(int i = 0;i<all.size();i++)
        {
            if(all[i]==' ')
                continue;   //跳过
            int num  = all.mid(i,2).toUInt(nullptr,16);
            i++;
            byteArray.append(num);
        }
        return byteArray;
    }
};

TcpClient* TcpClient::getInstance()
{
    if(Instance==0)
        Instance =new TcpClient();
    return Instance;
}

TcpClient::TcpClient(QObject *parent): QTcpSocket(parent)
{
    mapGZ = new QMap<QString, QString>();
    mapGZ->insert("0B","EEROM初始化错误");
    mapGZ->insert("0C","温度采集初始化失败");
    mapGZ->insert("0D","温度读取失败");
    mapGZ->insert("0E","A区温度过高");
    mapGZ->insert("0F","B区温度过高");
    mapGZ->insert("10","C区温度过高");
    mapGZ->insert("11","D区温度过高");
    mapGZ->insert("12","E区温度过高");
    mapGZ->insert("13","F区温度过高");
    mapGZ->insert("14","A区温度异常");
    mapGZ->insert("15","B区温度异常");
    mapGZ->insert("16","C区温度异常");
    mapGZ->insert("17","D区温度异常");
    mapGZ->insert("18","E区温度异常");
    mapGZ->insert("19","F区温度异常");
    mapGZ->insert("1A","水泵故障");
    mapGZ->insert("1B","风扇故障");
    mapGZ->insert("1C","仓门打开");
    mapGZ->insert("1D","ad模块通信异常");
    mapGZ->insert("1E","升降电机位置异常");
    mapGZ->insert("1F","开关门电机位置异常");

    //自动连接在信号发射时被识别为队列连接/信号在主线程发射
    connect(this, &TcpClient::SignalConnectToHost, this, [&](const QString & address, quint16 port) {
        this->abort();
        this->connectToHost(QHostAddress(address), port, QIODevice::ReadWrite);
        if(this->waitForConnected(1000)){
            MainWindow::tcpStatus.set(0);
        }else {
            MainWindow::tcpStatus.set(1);
        }
    }, Qt::AutoConnection);

    //连接了TCP服务端
    QObject::connect(this, &QAbstractSocket::connected, this, [&]() {
        MainWindow::tcpStatus.set(0);
        m_bOnLine = true;
        //        QTimer::singleShot(10000, this, SLOT(onTimeout()));
    }, Qt::DirectConnection);

    //断开了TCP服务端
    QObject::connect(this, &QAbstractSocket::disconnected, this, [&]() {
        m_bOnLine = false;
        if(MainWindow::experimentCircle.get()<20){
            int m=0;
            QString sql="Select * from ConnectionInfo";
            QSqlDatabase db = dbHelper::openConnection();

            QSqlQuery query(db);
            query.exec(sql);
            QString ip;
            int port;
            while (query.next()) {
                ip=query.value("Ip").toString();
                port=query.value("Port").toInt();
            }

            while(!m_bOnLine && m<5){
                common->Sleep(2);
                this->connectToHost(ip, port, QIODevice::ReadWrite);
                if(this->waitForConnected(1000)){
                    m_bOnLine=true;
                    break;
                }
                m++;
            }
        }

        if(!m_bOnLine){
            MainWindow::tcpStatus.set(1);
        }
    }, Qt::QueuedConnection);

    //收到了TCP服务的数据
    QObject::connect(this, &QIODevice::readyRead, this, [&]() {
        logClient=loghelper::getInstance();
        QByteArray arr = this->readAll();
        QString str;
        for(int c :arr)
        {
            if(c>=0)
            {
                str += QString(" %1").arg(c, 2, 16, QChar('0')).toUpper();
            }
            else
            {
                str += QString(" %1").arg(c+256, 2, 16, QChar('0')).toUpper();
            }
        }
        str= str.simplified();
        logClient->WriteLog("CommLog","接收:\n"+str);
        QStringList list=str.split(" ");
        if(list.length()>12){
            if(SampleWindow::startExperimentMsg.get()==1)
            {
                if(list[3]!="38"){
                    SampleWindow::startExperimentMsg.set(2);
                    return;
                }else{
                    SampleWindow::startExperimentMsg.set(0);
                }
            }

            if(MainWindow::experimentStatus.get()!=1){
                if(list[list.length()-2]=="AA"&& list[list.length()-1]=="55"){
                    if(tempString.isEmpty()){
                        tempString=str;
                    }else{
                        tempString.append(" "+str);
                    }
                    recvvalue = str;
                    recfl.set(1);

                }else{
                    tempString = str;
                    return ;
                }
            }

            if(list[0]=="62" && list[1]=="00" && list[2]=="00" )
            {
                if( list[3]=="3C" && list[7]=="07"){
                    if(true)//荧光数据
                    {
                        tempString.clear();
                        QStringList list=str.split(" ");
                        for(int i=12;i<list.length()-4;i+=10){
                            if(i+4>list.length()||i+5>list.length()||i+6>list.length()||i+7>list.length()||
                                    i+8>list.length()||i+9>list.length()){
                                break;
                            }
                            else
                            {
                                QSqlDatabase db = dbHelper::openConnection();
                                QSqlQuery query(db);

                                QString sql=QString("Insert into FluorescenceData values('','%1','%2','%3',"
                                                    "'%4','%5','%6','','','','')").arg(
                                            common->SixteenToTen(list[i]+" "+list[i+1]),
                                        common->SixteenToTen(list[11]),
                                        common->SixteenToTen(list[i+2]+" "+ list[i+3]),
                                        common->SixteenToTen(list[i+4]+" "+ list[i+5]),
                                        common->SixteenToTen(list[i+6]+" "+ list[i+7]),
                                        common->SixteenToTen(list[i+8]+" "+ list[i+9])
                                        );
                                query.exec(sql);
                            }
                        }


                        QSqlDatabase db = dbHelper::openConnection();
                        QSqlQuery query(db);
                        db.transaction();
                        QString sql=QString("update FluorescenceData set SampleId=(select id from sampleInfo s "
                                            "where "
                                            "case "
                                            "when FluorescenceData.PositionNumber %1 = 0 "
                                            "then s.RowNum=7 and s.ColNum=FluorescenceData.PositionNumber/8-1 "
                                            "else "
                                            "s.RowNum = FluorescenceData.PositionNumber %1-1 and s.ColNum = FluorescenceData.PositionNumber/8 "
                                            "end)").arg("%8");
                        query.exec(sql);

                        sql="DELETE FROM FluorescenceData WHERE rowid NOT IN (SELECT MIN(rowid) FROM FluorescenceData GROUP BY positionNumber, CyclesNumber)";
                        query.exec(sql);
                        db.commit();

                    }
                }
                else if (list[3]=="3D" || list[3]=="3C"){
                    if(list[list.length()-2]=="AA"&& list[list.length()-1]=="55"){
                        tempString.append(" "+str);
                        recvvalue = str;
                        recfl.set(1);

                    }else{
                        tempString = str;
                        return ;
                    }
                    tempString.clear();
                }
                else if(list[3]=="38"){
                    if(list[10]=="00" && list[11]=="00"){
                        MainWindow::startExperimentStatus.set(0);
                    }
                    else if(list[10]=="00" &&list[11]=="01"){
                        MainWindow::startExperimentStatus.set(1);
                    }
                    else if(list[10]=="00"&& list[11]=="02"){
                        MainWindow::startExperimentStatus.set(2);
                    }
                }
            }
            if((list[0]=="62" && list[1]=="00" && list[2]=="00" && list[3]=="3A")||!tempString.isEmpty())
            {
                if(list.length()==30 )//温度数据
                {
                    MainWindow::experimentStep.set(common->SixteenToTen(list[10]).toInt());
                    MainWindow::experimentCircle.set(common->SixteenToTen(list[11]).toInt());

                    QString tempOne =common->SixteenToTen(list[12]+" "+list[13]);
                    MainWindow::tempDataOne=tempOne.toDouble()/100;

                    QString tempTwo=common->SixteenToTen(list[14]+" "+list[15]);
                    MainWindow::tempDataTwo=tempTwo.toDouble()/100;

                    QString tempThree=common->SixteenToTen(list[16]+" "+list[17]);
                    MainWindow::tempDataThree=tempThree.toDouble()/100;

                    QString tempFour=common->SixteenToTen(list[18]+" "+list[19]);
                    MainWindow::tempDataFour=tempFour.toDouble()/100;

                    QString tempFive=common->SixteenToTen(list[20]+" "+list[21]);
                    MainWindow::tempDataFive=tempFive.toDouble()/100;

                    QString tempSix=common->SixteenToTen(list[22]+" "+list[23]);
                    MainWindow::tempDataSix=tempSix.toDouble()/100;

                    MainWindow::tempOrder = list[25].toInt();
                }
                if(list.length()>400)//荧光数据
                {
                    if(tempString.length()>4 && tempString.split(" ")[3]!="3A"){
                        tempString.clear();
                    }else if(tempString.length()>0 && tempString.length()<=4){
                        tempString.clear();
                    }

                    if(list[list.length()-2]!="AA"&& list[list.length()-1]!="55"){
                        tempString=str;
                        return;
                    }
                    else
                    {
                        QSqlDatabase db = dbHelper::openConnection();
                        QSqlQuery query(db);

                        db.transaction();

                        if(list[list.length()-2]=="AA"&& list[list.length()-1]=="55" && tempString.isEmpty())
                        {
                            tempString = str;
                        }
                        else
                        {
                            tempString.append(" "+str);
                        }
                        qDebug()<<tempString;

                        QStringList dataList=tempString.split(" ");
                        tempString.clear();

                        for(int i=12;i<dataList.length()-4;i+=10){
                            if(i+4>dataList.length()||i+5>dataList.length()||i+6>dataList.length()||i+7>dataList.length()||
                                    i+8>dataList.length()||i+9>dataList.length()){
                                db.commit();
                                break;
                            }else
                            {
                                QString sql=QString("Insert into FluorescenceData values('','%1','%2','%3',"
                                                    "'%4','%5','%6','','','','')").arg(
                                            common->SixteenToTen(dataList[i]+" "+dataList[i+1]),
                                        common->SixteenToTen(dataList[11]),
                                        common->SixteenToTen(dataList[i+2]+" "+ dataList[i+3]),
                                        common->SixteenToTen(dataList[i+4]+" "+ dataList[i+5]),
                                        common->SixteenToTen(dataList[i+6]+" "+ dataList[i+7]),
                                        common->SixteenToTen(dataList[i+8]+" "+ dataList[i+9])
                                        );
                                query.exec(sql);
                            }
                        }

                        QString sql=QString("update FluorescenceData set SampleId=(select id from sampleInfo s "
                                            "where "
                                            "case "
                                            "when FluorescenceData.PositionNumber %1 = 0 "
                                            "then s.RowNum=7 and s.ColNum=FluorescenceData.PositionNumber/8-1 "
                                            "else "
                                            "s.RowNum = FluorescenceData.PositionNumber %1-1 and s.ColNum = FluorescenceData.PositionNumber/8 "
                                            "end)").arg("%8");
                        query.exec(sql);

                        sql="DELETE FROM FluorescenceData WHERE rowid NOT IN (SELECT MIN(rowid) FROM FluorescenceData GROUP BY positionNumber, CyclesNumber)";
                        query.exec(sql);
                        db.commit();

//                        MainWindow::canRefChart.set(0);
                    }
                }
            }
        }

        eqptinfo eqInfo;
        QString errStatus=eqInfo.errStatusRead();

        if(errStatus=="0"){
            // cnr 07发送 6.25
            QString Data=str.remove(QRegExp("\\s"));
            QString ty = Data.mid(4,4);
            QString wendubs = Data.mid(8,4);
            QString isright = Data.mid(12,4);
            QString isright2 = Data.mid(16,4);
            QString rw = Data.mid(50,2);
            if(ty=="003A"){
                QString gzfl = Data.mid(Data.length()-10,2);
                if (wendubs=="0018"&&rw=="07"&&Data.length()==60) {
                    if(rw=="07"){
                        order order1;
                        this->write(order1.toByteArray("6200","003A","000A","000100010007","1652","55AA"));
                    }
                }else if(gzfl=="07"){
                    allerror.clear();
                    int flnum=0;
                    for(int i=24;i<=Data.length()-14;i+=2){
                        QString gzdz = Data.mid(i,2);
                        QString gzdzv=mapGZ->value(gzdz);
                        allerror += gzdzv+";";
                    }
                    MainWindow::experimentStatus.set(3);
                    infochan.set(infochan.get()+1);
                    allerror.clear();
                }
            }
        }


    }, Qt::DirectConnection);

    //执行数据发送过程
    QObject::connect(this, &TcpClient::SignalSendingData, this, [&](const QByteArray c_btaData){
        sendTitle=c_btaData[3];
        this->write(c_btaData);
    }, Qt::AutoConnection);
}

//
TcpClient::~TcpClient()
{
}

//跨线程转换
void TcpClient::ClientConnectToHost(const QString & address, quint16 port)
{
    emit SignalConnectToHost(address, port);
}

//跨线程转换
void TcpClient::ClientSendingData(const QByteArray & c_btaData)
{
    emit SignalSendingData(c_btaData);
}

//是否在线
bool TcpClient::IsOnline()
{
    return m_bOnLine;
}

void TcpClient::onTimeout(){
    order order1;
    this->write(order1.toByteArray("6200","003A","000A","000100010005","0000","55AA"));
}
